package ch.exm.storm.conditions;

import static ch.exm.storm.conditions.arguments.ArgumentsFactory.getActualArgument;

import java.util.HashSet;
import java.util.Set;

import ch.exm.storm.conditions.arguments.Argument;
import ch.exm.storm.conditions.arguments.ConstantEvaluatedArgument;
import ch.exm.storm.conditions.arguments.EvaluatedArgument;
import ch.exm.storm.query.relational.RelationalQuery;

public abstract class AbstractSimpleCondition extends AbstractCondition implements SimpleCondition {

	protected Object[] arguments;
	
	protected EvaluatedArgument evaluateArgument(Object object, RelationalQuery query) {
		Argument argument = getActualArgument(object);
		EvaluatedArgument evaluatedArgument = argument != null ? query.evaluateArgument(argument) : new ConstantEvaluatedArgument(object);
		if (evaluatedArgument.isFullyEvaluated()) whereCondition.append(evaluatedArgument.getEvaluatedPart());
		return evaluatedArgument;
	}
	
	protected String argumentToString(Object object) {
		Argument argument = getActualArgument(object);
		return argument == null ? object.toString() : argument.toString();
	}
	
	protected Object evaluteArgumentOn(Object param, Object object) {
		Argument argument = getActualArgument(param);
		return argument == null ? param : argument.evaluate(object);
	}
	
	protected boolean isRelationalArgument(RelationalQuery query, Object argument) {
		EvaluatedArgument evaluatedArgument = evaluateArgument(argument, query);
		boolean isRelational = evaluatedArgument.isFullyEvaluated();
		if (!isRelational) whereCondition.setLength(0);
		return isRelational;
	}
	
	protected Class<?> getRootArgumentClass(Object object) {
		Argument argument = getActualArgument(object);
		return argument != null ? argument.getRootArgumentClass() : null;
	}

	public final Set<Class<?>> getQueriedClasses() {
		Set<Class<?>> queriedClasses = new HashSet<Class<?>>();
		for (Object argument : arguments) {
			Class<?> argumentClass = getRootArgumentClass(argument);
			if (argumentClass != null) queriedClasses.add(argumentClass);
		}
		return queriedClasses;
	}

	protected abstract String getConditionKeyword();
	protected abstract String getInverseConditionKeyword();
}
